﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Circle.Domain.Interface.Service;
using Circle.Domain.Entity;
using Circle.Web.ViewModelsClient;
using System.Linq.Expressions;
using Circle.Web.ViewModels;
using Circle.Web.Drivers;
using Circle.Domain.Model;
using System.Data.Entity;
using Circle.Web.Drivers.Contract;
using Circle.Utility;
using Circle.Web.Application;
using Circle.Manager;
using LinqDynamicKit;

namespace Circle.Web.Drivers
{
    public class CommentDriver : OwnerableEntityDriver<ContentComment, CommentClientModel>, ICommentDriver 
    {
        private readonly ICommentService _commentService;


        public CommentDriver(ICommentService commentService)
            : base(commentService)
        {
            _commentService = commentService;
        }

        //public override PostClientModel GetClientModel(Guid? id = null, string includeProperty = null, string excludeProperty = null)
        //{
        //    var postClient = base.GetClientModel(id, includeProperty, excludeProperty);
        //    if (postClient.isNew())
        //    {
        //        postClient.ContentVote = new VoteClientModel();
        //    }
        //    return postClient;
        //}

        public override CommentClientModel CreateClient(string[] includeProperties = null)
        {
            var commentClient = base.CreateClient(includeProperties);

            if (includeProperties!= null && includeProperties.Contains("Vote"))
            {
                commentClient.Vote = new VoteClientModel();
                if (SecurityManager.CurrentUser != null)
                {
                    commentClient.Vote.UserName = SecurityManager.CurrentUser.UserName;
                }
            }

            return commentClient;
        }

        public override CommentClientModel ToClient(ContentComment entity, CommentClientModel cModel = null, string[] excludeProperties = null, bool serverStatus = true)
        {
            if (entity == null) return null;

            CommentClientModel commentClient = base.ToClient(entity, cModel, excludeProperties, serverStatus);


            if (excludeProperties == null || !excludeProperties.Contains("Vote"))
            {
                if (commentClient.Vote == null) { commentClient.Vote = new VoteClientModel(); }

                commentClient.Vote.UserName = entity.UserName;
                commentClient.Vote.VoteUpCount = entity.VoteUpCount;
                commentClient.Vote.VoteDownCount = entity.VoteDownCount;
                commentClient.Vote.CommentId = entity.Id;
            }


            if(entity.Topic != null)
            {
                commentClient.ThreadId = entity.Topic.ThreadId;
                commentClient.TopicTitle = entity.Topic.Title;
                commentClient.TopicSubTitle = entity.Topic.SubTitle;
                commentClient.TopicThumbnail = entity.Topic.Thumbnail;
            }
            commentClient.Content = entity.Content;
            commentClient.TopicId = entity.TopicId;
            commentClient.CreateTime = entity.CreateTime;
            commentClient.LastUpdateTime = entity.LastUpdateTime;

            return commentClient;
        }

        public override ContentComment FromClient(ContentComment m, CommentClientModel cModel, string[] includeProperties = null)
        {
            ContentComment comment = base.FromClient(m, cModel, includeProperties);
            if (comment == null) return null;

            comment.Content = cModel.Content;
            if (comment.IsNew())
            {
                comment.TopicId = cModel.TopicId;
            }

            if (includeProperties!=null && includeProperties.Contains("Vote"))
            {
                comment.VoteUpCount = cModel.Vote.VoteUpCount;
                comment.VoteDownCount = cModel.Vote.VoteDownCount;
            }

            return comment;
        }

        public override OperationStatus Save(CommentClientModel cModel, string[] includeProperties = null, string[] excludeProperties = null)
        {
            return base.Save(cModel, null, excludeProperties);
        }

        public bool HasPermission(EntityPermission permission, ContentComment contentComment = null, Guid? threadId = null)
        {
            return _commentService.HasPermission(permission, contentComment, threadId);
        }

        public PageListClient<CommentClientModel> PagingMyClientComments(int pageIndex, int pageSize, string sort)
        {
            Expression<Func<ContentComment, bool>> predicate = PredicateBuilder.True<ContentComment>();
            predicate = predicate.And(x => x.UserId == SecurityManager.CurrentUser.UserId);
            predicate = predicate.Expand();

            var pageComments = _commentService.Paging(pageIndex, pageSize, sort, predicate, new string[]{"Topic"});
            PageListClient<CommentClientModel> page = new PageListClient<CommentClientModel>(pageComments);
            foreach (var comment in pageComments)
            {
                page.Add(ToClient(comment, excludeProperties: new string[] { "Vote" }));
            }

            return page;
        }

    }
}